<?php
/**
 *备货规则模型
 *@author shipanpan
 */
class Cron_Model_Backup_BackupRule extends Model_Base {

	public function __construct() {
		$this->db = $this->db();
		$this->writeDb = $this->db("write_db");
	}

	/**
	 * 获取一条备货规则
	 * @param  int    $ruleId [description]
	 * @return [type]         [description]
	 */
	public function getOne(int $ruleId) {
		$backupRule = $this->db->fetchRow("select * from b_product_backup_rule where id=?", $ruleId);
		if (!$backupRule) {
			return $this->_error('未找到指定的备货规则！');
		}
		return $backupRule;
	}

	/**
	 * 获取一条备货规则详情(包括备货规则的分类规则)
	 * @param int $ruleId 备货规则id
	 * @return 未找到返回false,成功返回array,其中备货规则的分类规则放在键值‘filter_rule’
	 */
	public function getDetail(int $ruleId) {
		$backupRule = $this->getOne($ruleId);
		if (!$backupRule) {
			return false;
		}
		$backupRuleFilterRule = $this->db->fetchAll('select * from b_product_backup_rule_filter_rule where backup_rule_id=?', $backupRule['id']);
		$backupRule['filter_rule'] = $backupRuleFilterRule;
		return $backupRule;
	}

	/**
	 * 获取备货规则适用的仓库的仓库代码
	 * @param  int    $backupRuleId [description]
	 * @return array|false
	 */
	public function ruleApplyWarehouse(int $backupRuleId) {
		$backupRule = $this->getOne($backupRuleId);
		if (!$backupRule) {
			return $this->_error("备货规则的适用仓库为空！");
		}

		$ruleWarehouseIdStr = $backupRule['warehouse'];
		$ruleWarehouseId = explode(",", $ruleWarehouseIdStr);

		$commWarehouseModel = new Application_Model_Warehouse();
		$warehouseDetail = $commWarehouseModel->getWarehouseById($ruleWarehouseId, ['id', 'warehouse_code']);
		return array_column($warehouseDetail, 'warehouse_code');
	}

	/**
	 *执行备货规则,对符合备货规则的分类规则商品全部进行备货
	 * @return [type]              [description]
	 */
	public function run(int $ruleId) {
		$log = new Log();
		$ruleInfo = $this->getOne($ruleId);
		if (empty($ruleInfo)) {
			return $this->_error("未找到id为：" . $ruleId . "的备货规则！");
		}

		$backupRuleFilterRuleModel = new Cron_Model_Backup_BackupRuleFilterRule();

		$ruleApplyWarehouse = $this->ruleApplyWarehouse($ruleId);
		if (empty($ruleApplyWarehouse)) {
			return $this->_error("未找到备货规则'" . $ruleInfo['name'] . "'的适用的仓库！");
		}

		foreach ($ruleApplyWarehouse as $_warehouse) {
			$warehouseMatchGoodsTotalNum = $backupRuleFilterRuleModel->getWarehouseMatchGoodsTotalNum($ruleId, $_warehouse);
			if ($warehouseMatchGoodsTotalNum === false) {
				$errMsg = "备货规则:'" . $ruleInfo['name'] . "'的分类规则解析发生错误，原因是:" . $backupRuleFilterRuleModel->getErrorMsg();
				return $this->_error($errMsg);
			}
			if (!$warehouseMatchGoodsTotalNum) {
				$log->record("备货规则:'" . $ruleInfo['name'] . '在适用仓库' . $_warehouse . '筛选商品为空！', Log::WARN);
				continue;
			}

			//避免数据过多，分批处理
			$everyTimeHandleNum = 2000;
			$handleTimes = ceil($warehouseMatchGoodsTotalNum / $everyTimeHandleNum);
			for ($i = 0; $i < $handleTimes; $i++) {
				$offset = $i * $everyTimeHandleNum;
				$matchGoods = $backupRuleFilterRuleModel->getWarehouseMatchGoods($ruleId, $_warehouse, $offset, $everyTimeHandleNum);

				if ($matchGoods === false) {
					$errMsg = "备货规则:'" . $ruleInfo['name'] . "'的分类规则解析发生错误，原因是:" . $backupRuleFilterRuleModel->getErrorMsg();
					return $this->_error($errMsg);
				}
				if (empty($matchGoods)) {
					continue;
				}

				foreach ($matchGoods as $_goodsSn) {
					$autoBackupProduct = new Cron_Model_Backup_AutoBackupProduct($_goodsSn, $_warehouse, $ruleInfo);
					$createStoryResult = $autoBackupProduct->createStory();
					if ($createStoryResult === false) {
						$log->record('商品：' . $_goodsSn . '计算c需求发生错误，原因是:' . $autoBackupProduct->getErrorMsg(), Log::WARN);
					}

					//被某一条备货规则筛选出来的商品，不管是否出c需求，都不在使用其他备货规则来备货c需求
					$updateWhere = $this->writeDb->quoteInto("goods_sn=?", $_goodsSn);
					$updateWhere .= " AND " . $this->writeDb->quoteInto("warehouse=?", $_warehouse);
					$this->writeDb->update("tmp_30days_has_sales_product", ['is_count_c_story' => 1], $updateWhere);
				}
			}

		}
		return true;
	}

	/**
	 * 获取当前有效的备货规则
	 * @return [type] [description]
	 */
	public function getAvailableRule() {
		$curDate = date("Y-m-d");
		return $this->db->fetchAll("select * from b_product_backup_rule where start_date<=" . $this->db->quote($curDate) . " and end_date>=" . $this->db->quote($curDate) . " AND is_enable=1 and is_delete=0 and is_simulation_type=0 order by priority");
	}

}